package net.phoenix.repository.nodetype;

import java.io.File;
import java.io.FilenameFilter;
import java.io.IOException;
import java.util.List;
import java.util.Vector;

import javax.jcr.RepositoryException;
import javax.jcr.UnsupportedRepositoryOperationException;
import javax.jcr.nodetype.InvalidNodeTypeDefinitionException;
import javax.jcr.nodetype.NodeType;
import javax.jcr.nodetype.NodeTypeDefinition;
import javax.jcr.nodetype.NodeTypeExistsException;
import javax.jcr.nodetype.NodeTypeIterator;

import net.phoenix.repository.data.NodeTypeData;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.xml.sax.SAXException;

/**
 * Jigsaw server
 * 
 * @author <a href="shamphone@gmail.com">Li XiongFeng</a>
 * @date 2012-5-28
 * @version 1.0.0
 */
public class XMLNodeTypeDefinitionManager extends GeneralNodeTypeManager {
	private static final Log log = LogFactory.getLog(XMLNodeTypeDefinitionManager.class);
	private XMLNodeTypeParser parser;

	public XMLNodeTypeDefinitionManager() {
		this.parser = new XMLNodeTypeParser();
	}

	/**
	 * init database configuration. load default type definition;
	 * 
	 * @throws Exception
	 */
	public void loadFromFolder(File folder) throws IOException {
		folder.listFiles(new FilenameFilter() {

			@Override
			public boolean accept(File dir, String name) {
				if (name.endsWith(".def.xml")) {
					File file = new File(dir, name);
					try {
						loadNodeTypeFile(file);
						log.info("Load node type from " + file.getPath());
						return true;
					} catch (IOException e) {
						log.error("IO error load definition from " + file.getPath(), e);
					} catch (SAXException e) {
						log.error("SAX error load definition from " + file.getPath(), e);
					}

				}
				return false;
			}
		});

	}

	/**
	 * load node type from file;
	 * 
	 * @param file
	 * @return
	 * @throws IOException
	 * @throws SAXException
	 */
	public NodeTypeDefinition loadNodeTypeFile(File file) throws IOException, SAXException {
		NodeTypeData data = this.parser.parser(file);
		NodeType definition = new XMLNodeType(this, data);
		this.addNodeType(definition);
		return definition;
	}

	@Override
	public NodeType registerNodeType(final NodeTypeDefinition ntd, boolean allowUpdate) throws InvalidNodeTypeDefinitionException, NodeTypeExistsException, UnsupportedRepositoryOperationException,
			RepositoryException {	
		return (NodeType) ntd;
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see
	 * javax.jcr.nodetype.NodeTypeManager#registerNodeTypes(javax.jcr.nodetype.NodeTypeDefinition[], boolean)
	 */
	@Override
	public NodeTypeIterator registerNodeTypes(NodeTypeDefinition[] ntds, boolean allowUpdate) throws InvalidNodeTypeDefinitionException, NodeTypeExistsException,
			UnsupportedRepositoryOperationException, RepositoryException {
		List<NodeType> types = new Vector<NodeType>();
		for (int i = 0; i < ntds.length; i++)
			types.add(this.registerNodeType(ntds[i], allowUpdate));
		return new BasicNodeTypeIterator(types);
	}



}
